import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
	public static void main(String[] args) {
		System.out
				.println("ESP Helper 0.6 by Michael Schwarz (michael.schwarz@student.tugraz.at)");
		System.out
				.println("---------------------------------------------------------------------");
		System.out.println();

		// show usage
		if (args.length < 2) {
			System.out
					.println("esphelper <deliveries.zip|-> <c-file|-> [--skip-software-check] [--transpose]");
			return;
		}

		String file = args[0];
		String delv_name = args[1];

		List<String> files_to_check = new ArrayList<String>();
		if (!args[1].equals("-")) {
			// get all files to check
			for (int i = 1; i < args.length; i++) {
				if (!args[i].startsWith("--"))
					files_to_check.add(args[i]);
			}
		}

		// get working directory
		String working_dir = System.getProperty("user.dir");

		String directory = working_dir;
		if (file.lastIndexOf('/') != -1)
			directory = file.substring(0, file.lastIndexOf('/'));

		if (Arrays.asList(args).contains("--skip-software-check")) {
			// check if python is installed
			if (!Checker.checkForPython()) {
				System.err.println("[Error] Python must be installed!");
				return;
			}
			// check if uncrustify is installed
			if (!Checker.checkForUncrustify()) {
				System.err.println("[Error] Uncrustify must be installed!");
				return;
			}
			// check if diff is installed
			if (!Checker.checkForDiff()) {
				System.err.println("[Error] Diff must be installed!");
			}
			// check if gccxml is installed
			if (!Checker.checkForGCCXML()) {
				System.err.println("[Error] GCCXML must be installed!");
			}
			System.out.println();
		}

		// check if there is already a result.xls
		List<String> files = DirList.list(directory, null);
		if (files.contains("result.xls")) {
			System.err
					.println("[Error] result.xls already exists. Delete file and folder with assignments");
			return;
		}

		// create result file writer
		ResultWriter out = new ResultWriter(directory + "/result.xls");
		if (Arrays.asList(args).contains("--transpose"))
			out.transposeSheet(true);
		out.addLabel(0, 0, "Automated correction results");

		// extract coding standard config and diff2html
		Unzip.fromJar("check.cfg", working_dir);
		Unzip.fromJar("diff2html.py", working_dir);

		// unzip palme file
		if (!file.equals("-")) {
			Unzip.extract(file, directory);
			// go into first subfolder
			List<String> subdir = DirList.list(directory, DirList.dirFilter);
			if (subdir.size() != 1) {
				System.out
						.println("[Error] Wrong zip, too many subdirectories");
				return;
			}
			directory += "/" + subdir.get(0);

			// get directories
			List<String> dirs = DirList.list(directory, DirList.dirFilter);
			// directory must only contain homework
			if (dirs.size() > 1) {
				System.out
						.println("Error: zip file must be in empty directory!");
				return;
			}
			String ass_dir = directory + "/" + dirs.get(0) + "/";

			// list all folders
			List<String> delivery_folder = DirList.list(ass_dir,
					DirList.dirFilter);

			// show info
			System.out.println("[Info] Found " + delivery_folder.size()
					+ " deliveries");

			// write number of deliveries
			out.addLabel(0, 2, "Deliveries:");
			out.addNumber(1, 2, delivery_folder.size());

			out.addLabel(0, 5, "Mat#");

			// now do all the tests
			Pattern p = Pattern
					.compile("Matrikelnummer_(\\d+)_Assignmentgruppe_(\\d+)");
			Pattern p1 = Pattern.compile("Assignmentgruppe_(\\d+)");
			for (int i = 0; i < delivery_folder.size(); i++) {
				String folder = ass_dir + delivery_folder.get(i) + "/";
				String testreport = null;

				// check if we have testreports
				List<String> f_struct = DirList.list(folder, DirList.dirFilter);
				if (f_struct.size() == 2 && f_struct.contains("Testreport")) {
					// get folder of testreport
					testreport = folder + "Testreport/";
					List<String> tst_dir = DirList.list(testreport,
							DirList.dirFilter);
					if (tst_dir.size() == 1) {
						testreport += tst_dir.get(0) + "/";
					}
					folder += "Abgabe/";
				}

				// add group nr and matrikelnumber
				Matcher m = p.matcher(delivery_folder.get(i));
				if (m.find()) {
					out.addLink(i + 1, 4, folder, m.group(2));
					out.addLabel(i + 1, 5, m.group(1));
				} else {
					m = p1.matcher(delivery_folder.get(i));
					if (m.find()) {
						out.addLink(i + 1, 4, folder, m.group(1));
						out.addLabel(i + 1, 5, m.group(1));
					}
				}

				// unzip file
				List<String> arch = DirList.list(folder, null);
				if (arch.size() != 1) {
					out.addLabel(i + 1, 6, "no delivery!");
					continue;
				}
				Unzip.extract(folder + arch.get(0), folder);
				// delete zip
				File f = new File(folder + arch.get(0));
				f.delete();
				
				List<String> del = DirList.list(folder, null);
				
				boolean clear_files_to_check = false;
				if(files_to_check.size() == 0) {
					clear_files_to_check = true;
					for(String df : del) {
						if(df.endsWith(".cpp") || df.endsWith(".c")) files_to_check.add(df);
					}
				}

				// check for errors
				System.out.println("Checking delivery " + (i + 1));
				Checker check = new Checker(out, folder, testreport,
						files_to_check, 6);
				check.check(i + 1);
				
				if(clear_files_to_check) files_to_check.clear();
			}
		} else {
			// check only a single file

			// get working directory
			directory = working_dir;
			file = delv_name;
			if (delv_name.lastIndexOf('/') != -1) {
				directory = delv_name.substring(0, delv_name.lastIndexOf('/'));
				file = delv_name.substring(delv_name.lastIndexOf('/') + 1);
			}

			System.out.println("Checking delivery " + delv_name);
			Checker check = new Checker(out, directory, "", files_to_check, 6);
			check.check(1);

		}

		// remove cs and diff2html
		(new File("check.cfg")).delete();
		(new File("diff2html.py")).delete();

		// close excel file
		out.close();

		System.out.println("Done!");

	}
}
